<#assign object = doc.objects>
package ${object.package}.client;

import java.util.ArrayList;
import java.util.List;

import org.gwt.beansbinding.core.client.BeanProperty;
import org.gwt.beansbinding.core.client.AutoBinding.UpdateStrategy;
import org.gwt.beansbinding.core.client.ext.BeanAdapterFactory;
import org.gwt.beansbinding.core.client.util.AbstractBean;
import org.gwt.beansbinding.core.client.util.GWTBeansBinding;
import org.gwt.beansbinding.observablecollections.client.ObservableCollections;
import org.gwt.beansbinding.ui.client.GWTBindings;
import org.gwt.beansbinding.ui.client.GridBinding;
import org.gwt.beansbinding.ui.client.adapters.HTMLTableAdapterProvider;
import org.gwt.beansbinding.ui.client.adapters.HasTextAdapterProvider;


import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.smartgwt.client.util.JSON;
import com.smartgwt.client.util.SC;

public class AttributeFieldsView extends Composite {
	static {
		GWTBeansBinding.init();

		// Register all Adapters used in code
		BeanAdapterFactory.addProvider(new HasTextAdapterProvider());
		BeanAdapterFactory.addProvider(new HTMLTableAdapterProvider());
	}

	private int selectedRow = -1;

	List<AttributeField> fields = ObservableCollections
			.observableList(new ArrayList<AttributeField>());

	String url = URL.encode(GWT.getModuleBaseURL()
			+ "modelFieldsView.do?action=getFields");

	public AttributeFieldsView(String modelName) {
		final Grid grid = new Grid();
		grid.setCellSpacing(0);
		grid.setBorderWidth(1);

		addSimpleSelectionModel(grid);

		url = url + "&objectName=" + modelName;

		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
		builder.setCallback(new RequestCallback() {
			public void onError(Request request, Throwable exception) {
				SC.warn("upgrade failed!");
			}

			public void onResponseReceived(Request request, Response response) {
				JSONArray jsonAttributeFields = new JSONArray(JSON
						.decode(response.getText()));
				for (int i = 0; i < jsonAttributeFields.size(); i++) {
					JSONObject value = jsonAttributeFields.get(i).isObject();
					AttributeField field = new AttributeField();
					copyValue(field, value);
					fields.add(field);
				}
				GridBinding<AttributeField, List<AttributeField>, Grid> gridBinding = GWTBindings
						.createGridBinding(UpdateStrategy.READ, fields, grid);

				// define the property to be used to derive list elements
				BeanProperty<AttributeField, String> field_NameP = BeanProperty
						.create("field_name");
				BeanProperty<AttributeField, String> field_typeP = BeanProperty
						.create("field_type");
				BeanProperty<AttributeField, Boolean> not_nullP = BeanProperty
						.create("not_null");
				BeanProperty<AttributeField, Boolean> finderP = BeanProperty
						.create("finder");
				BeanProperty<AttributeField, Boolean> lazyP = BeanProperty
						.create("lazy");
				BeanProperty<AttributeField, String> regexpP = BeanProperty
						.create("regexp");
				BeanProperty<AttributeField, String> maxlengthP = BeanProperty
						.create("maxlength");

				// add the detail binding
				gridBinding.addColumnBinding(field_NameP).setColumnName(
						"field_name");
				gridBinding.addColumnBinding(field_typeP).setColumnName(
						"field_type");
				gridBinding.addColumnBinding(not_nullP).setColumnName(
						"not_null");
				gridBinding.addColumnBinding(finderP).setColumnName("finder");
				gridBinding.addColumnBinding(lazyP).setColumnName("lazy");
				gridBinding.addColumnBinding(regexpP).setColumnName("regexp");
				gridBinding.addColumnBinding(maxlengthP).setColumnName(
						"maxlength");
				gridBinding.bind();

			}
		});
		try {
			builder.send();
		} catch (RequestException e) {
			e.printStackTrace();
		}
		FlowPanel panel = new FlowPanel();
		grid.setWidth("100%");
		panel.add(grid);
		this.initWidget(panel);
	}

	private void addSimpleSelectionModel(final Grid grid) {
		grid.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				Cell cell = grid.getCellForEvent(event);
				if (cell != null) {
					if (selectedRow != -1) {
						DOM
								.setStyleAttribute(grid.getRowFormatter()
										.getElement(selectedRow),
										"backgroundColor", "");
					}
					selectedRow = cell.getRowIndex();
					if (selectedRow != -1) {
						DOM.setStyleAttribute(grid.getRowFormatter()
								.getElement(selectedRow), "backgroundColor",
								"#adcce7");
					}
				}
			}
		});
	}

	private void copyValue(AttributeField field, JSONObject value) {
		if (value.get("field_name") != null
				&& !value.get("field_name").toString().equalsIgnoreCase("null"))
			field.setField_name(value.get("field_name").isString()
					.stringValue());
		if (value.get("field_type") != null
				&& !value.get("field_type").toString().equalsIgnoreCase("null"))
			field.setField_type(value.get("field_type").isString()
					.stringValue());
		if (value.get("not_null") != null
				&& !value.get("not_null").toString().equalsIgnoreCase("null"))
			field.setNot_null(Boolean.valueOf(value.get("not_null").isString()
					.stringValue()));
		if (value.get("finder") != null
				&& !value.get("finder").toString().equalsIgnoreCase("null"))
			field.setFinder(Boolean.valueOf(value.get("finder").isString()
					.stringValue()));
		if (value.get("lazy") != null
				&& !value.get("lazy").toString().equalsIgnoreCase("null"))
			field.setLazy(Boolean.valueOf(value.get("lazy").isString()
					.stringValue()));
		if (value.get("regexp") != null
				&& !value.get("regexp").toString().equalsIgnoreCase("null"))
			field.setRegexp(value.get("regexp").isString().stringValue());
		if (value.get("maxlength") != null
				&& !value.get("maxlength").toString().equalsIgnoreCase("null"))
			field.setMaxlength(value.get("maxlength").isString().stringValue());
	}

	public class AttributeField extends AbstractBean {

		private String field_name;

		private String field_type;

		private boolean not_null;

		private boolean finder;

		private boolean lazy;

		private String regexp;

		private String maxlength;

		public String getField_name() {
			return field_name;
		}

		public void setField_name(String fieldName) {
			field_name = fieldName;
		}

		public String getField_type() {
			return field_type;
		}

		public void setField_type(String fieldType) {
			field_type = fieldType;
		}

		public boolean isNot_null() {
			return not_null;
		}

		public void setNot_null(boolean notNull) {
			not_null = notNull;
		}

		public boolean isFinder() {
			return finder;
		}

		public void setFinder(boolean finder) {
			this.finder = finder;
		}

		public boolean isLazy() {
			return lazy;
		}

		public void setLazy(boolean lazy) {
			this.lazy = lazy;
		}

		public String getRegexp() {
			return regexp;
		}

		public void setRegexp(String regexp) {
			this.regexp = regexp;
		}

		public String getMaxlength() {
			return maxlength;
		}

		public void setMaxlength(String maxlength) {
			this.maxlength = maxlength;
		}
	}
}
